package com.ns.core.utils.rsa;

import com.alibaba.fastjson2.JSONObject;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.ns.core.current.config.SysConst;
import com.ns.core.utils.cache.RedisUtil;
import com.ns.core.utils.sg.ResultError;
import org.springframework.util.StringUtils;

import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.util.Date;
import java.util.Map;

/**
 * Token 解析
 *
 * @author liao.wei
 * @since 2022/6/13
 */
public class TokenUtil {


    /**
     * 解析 token
     *
     * @param token token值
     */
    public static JSONObject parseToken(String token) {
        JSONObject secureObj = JSONObject.of();
        try {
            if (StringUtils.hasText(token)) {
                RSAPrivateKey privateKey = RsaUtil.getPrivateKey(RsaUtil.PRIVATE_KEY_STRING);
                RSAPublicKey publicKey = RsaUtil.getPublicKey(RsaUtil.PUBLIC_KEY_STRING);
                Algorithm algorithm = Algorithm.RSA256(publicKey, privateKey);
                JWTVerifier verifier = JWT.require(algorithm).build();
                DecodedJWT jwt = verifier.verify(token);
                Map<String, Claim> claims = jwt.getClaims();
                for (Map.Entry<String, Claim> entry : claims.entrySet()) {
                    secureObj.put(entry.getKey(), entry.getValue().as(Object.class).toString());
                }
            }
        } catch (Exception exception) {
            throw new ResultError(exception);
        }
        return secureObj;
    }

    /**
     * 生成token
     *
     * @param userInfo 用户信息
     * @return String
     */
    public static String generateToken(String userInfo) {
        return getAlgorithm(userInfo);
    }

    private static String getAlgorithm(String userInfo) {
        Algorithm algorithm;
        try {
            RSAPrivateKey privateKey = RsaUtil.getPrivateKey(RsaUtil.PRIVATE_KEY_STRING);
            RSAPublicKey publicKey = RsaUtil.getPublicKey(RsaUtil.PUBLIC_KEY_STRING);
            algorithm = Algorithm.RSA256(publicKey, privateKey);
        } catch (Exception e) {
            return null;
        }
        Date expireDate = new Date(System.currentTimeMillis() + RedisUtil.TTL * 60 * 60 * 1000);
        return JWT.create().withExpiresAt(expireDate).withAudience().withClaim(SysConst.TOKEN, userInfo).sign(algorithm);
    }
}
